package com.dudu.timer;

import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;

import com.dudu.bean.MeetInfoBean;
import com.dudu.bean.PoolAbilityInfoBean;
import com.dudu.bean.PoolNumberBean;
import com.dudu.bean.SendNoticeBean;
import com.dudu.dao.SendNoticeDao;
import com.dudu.dao.UploadFileDao;
import com.dudu.enumeration.AbilityTypeEnum;
import com.dudu.model.PushNoticeInfo;
import com.dudu.model.SendNotice;
import com.dudu.model.UploadFileModel;
import com.dudu.service.IMeetInfoService;
import com.dudu.service.IPoolNumberService;
import com.dudu.service.IPoolNumberUtilsService;
import com.dudu.service.impl.MeetInfoServiceImpl;
import com.dudu.service.impl.PoolNumberServiceImpl;
import com.dudu.service.impl.PoolNumberUtilsServiceImpl;
import com.dudu.utils.DateUtils;
import com.dudu.utils.HttpRequest;

import core.CoreDao;

public class SendVoiceUtil {

    private static final Logger log = core.util.Logger.getLogger(SendVoiceUtil.class.getSimpleName());
    private static SendNoticeDao mSendNoticeDao = new SendNoticeDao();
    private static IMeetInfoService meetImsService = new MeetInfoServiceImpl();
    private static UploadFileDao uploadfileDao = new UploadFileDao();
    // 号码配置信息查询
    private IPoolNumberService poolNumberService = new PoolNumberServiceImpl();
    // 号码池号码能力配置查询
    private IPoolNumberUtilsService poolNumberUtilsService = new PoolNumberUtilsServiceImpl();

    /**
     * 向通道上传语音文件
     * 
     * @param coreDao
     * @param fileModel
     * @param mediaName
     * @param voice_type
     * @return
     */
    public static JSONObject uploadFile(CoreDao coreDao, UploadFileModel fileModel, String mediaName, String voice_type) {
	JSONObject object = new JSONObject();
	if (StringUtils.isBlank(fileModel.getVoice_name())) {
	    // 上传
	    log.info("开始上传文件" + mediaName);
	    UploadFileThread uploadFileThread = new UploadFileThread(coreDao, fileModel, voice_type, mSendNoticeDao, uploadfileDao);
	    uploadFileThread.start();
	} else {
	    if (voice_type.startsWith(AbilityTypeEnum.AUDEOSEND.getKey()) || voice_type.equals(AbilityTypeEnum.IVR_IMS.getKey())) {
		// ims
		if (!fileModel.getAbilityType().equals("ims")) {
		    object.put("result", "-1");
		    object.put("describe", "请先上传语音文件");
		    object.put("errorMsg", "请先上传语音文件.abilitytype:" + voice_type + ";文件类型:" + fileModel.getAbilityType());
		    object.put("code", "0509");
		    return object;
		}
	    } else if (voice_type.startsWith(AbilityTypeEnum.RONGLIANAUDEO.getKey()) || voice_type.equals(AbilityTypeEnum.IVR_RONGL.getKey())) {
		// 荣联
		if (!fileModel.getAbilityType().equals("ronglian")) {
		    object.put("result", "-1");
		    object.put("describe", "请先上传语音文件");
		    object.put("errorMsg", "请先上传语音文件.abilitytype:" + voice_type + ";文件类型:" + fileModel.getAbilityType());
		    object.put("code", "0509");
		    return object;
		}
	    } else if (voice_type.startsWith(AbilityTypeEnum.TIANYIAUDEO.getKey()) || voice_type.equals(AbilityTypeEnum.IVR_TianYi.getKey())) {
		// 天亿
		if (!fileModel.getAbilityType().equals("tianyi")) {
		    object.put("result", "-1");
		    object.put("describe", "请先上传语音文件");
		    object.put("errorMsg", "请先上传语音文件.abilitytype:" + voice_type + ";文件类型:" + fileModel.getAbilityType());
		    object.put("code", "0509");
		    return object;
		}
	    } else if (voice_type.startsWith(AbilityTypeEnum.YONYOUAUDEO.getKey()) || voice_type.equals(AbilityTypeEnum.IVR_YONYOU.getKey())) {
		// 自建平台
		if (!fileModel.getAbilityType().equals("yonyou")) {
		    object.put("result", "-1");
		    object.put("describe", "请先上传语音文件");
		    object.put("errorMsg", "请先上传语音文件.abilitytype:" + voice_type + ";文件类型:" + fileModel.getAbilityType());
		    object.put("code", "0509");
		    return object;
		}
	    } else {
		object.put("result", "-1");
		object.put("describe", "请先上传语音文件");
		object.put("errorMsg", "请先上传语音文件.abilitytype:" + voice_type);
		object.put("code", "0509");
		return object;
	    }

	}
	object.put("result", "0");
	return object;
    }

    /**
     * 获取显号号码
     * 
     * 号码来源：通道提供：external，用户提供：custom，内部号码：inside,公共号码池：general
     * 
     * @param app_key
     *            应用KEY
     * @param cust_account
     *            账号KEY
     * @param ability_Type
     *            能力类型
     * @param pool_ability_id
     *            能力ID
     * @param displayNbr
     *            能力显号
     * @param usePlatNbr
     *            强制使用平台号码(值为1时，强制使用平台号码发起)
     * @param number_vest
     *            地区
     * @return
     */
    public PoolAbilityInfoBean queryPoolAbilityInfo(CoreDao coreDao, String app_key, String cust_account, String ability_Type, String pool_ability_id, String displayNbr,
	    String usePlatNbr, String number_vest) {
	PoolAbilityInfoBean poolAbilityInfo = null;
	if (StringUtils.isNotBlank(displayNbr) && StringUtils.isNotBlank(pool_ability_id)) {
	    // displayNbr与pool_ability_id都不能为空
	    poolAbilityInfo = poolNumberService.getPoolAbilityNumberById(pool_ability_id);
	    // 判断如果查询到的号码为空，则查询配置的号码
	    if (poolAbilityInfo == null) {
		// 查询相应号码
		poolAbilityInfo = poolNumberUtilsService.getPoolNumberInfoFilter(coreDao, app_key, cust_account, ability_Type, usePlatNbr, number_vest);
	    } else {
		if (poolAbilityInfo.getDisplay_number().equals(displayNbr)) {
		    // gaoxs 增加计数
		    poolNumberUtilsService.recordNumTime(coreDao, app_key, cust_account, pool_ability_id, null);
		}
	    }
	} else if (StringUtils.isNotBlank(displayNbr)) {
	    // 显号displayNbr
	    poolAbilityInfo = poolNumberUtilsService.getPoolNumberInfo(coreDao, app_key, cust_account, ability_Type, displayNbr, usePlatNbr, number_vest);
	    // 判断如果查询到的号码为空，则查询配置的号码
	    if (poolAbilityInfo == null) {
		// 查询相应号码

		poolAbilityInfo = poolNumberUtilsService.getPoolNumberInfoFilter(coreDao, app_key, cust_account, ability_Type, usePlatNbr, number_vest);
	    } else {
		// gaoxs 增加计数
		poolNumberUtilsService.recordNumTime(coreDao, app_key, cust_account, pool_ability_id, null);
	    }
	} else if (StringUtils.isNotBlank(pool_ability_id)) {
	    // pool_ability_id
	    poolAbilityInfo = poolNumberService.getPoolAbilityNumberById(pool_ability_id);
	    // 判断如果查询到的号码为空，则查询配置的号码
	    if (poolAbilityInfo == null) {
		// 查询相应号码
		poolAbilityInfo = poolNumberUtilsService.getPoolNumberInfoFilter(coreDao, app_key, cust_account, ability_Type, usePlatNbr, number_vest);
	    } else {
		// gaoxs 增加计数
		poolNumberUtilsService.recordNumTime(coreDao, app_key, cust_account, pool_ability_id, null);
	    }
	} else {
	    // 查询相应号码
	    poolAbilityInfo = poolNumberUtilsService.getPoolNumberInfoFilter(coreDao, app_key, cust_account, ability_Type, usePlatNbr, number_vest);
	}
	// 配置为空时，查询默认号码
	if (poolAbilityInfo == null) {
	    poolAbilityInfo = poolNumberService.queryDefaultPoolAbilityNumber(ability_Type, "general");// 公共号码池
	} else if (!poolAbilityInfo.getAbility_type().equals(ability_Type)) {//
	    // poolAbilityInfo=poolNumberService.queryDefaultPoolAbilityNumber(ability_Type,
	    // "general");//公共号码池
	    return null;
	}
	if (poolAbilityInfo != null) {
	    PoolNumberBean bean = poolNumberService.queryPoolNumberById(poolAbilityInfo.getPool_id());
	    poolAbilityInfo.setNumber_source(bean.getNumber_source());
	    return poolAbilityInfo;
	} else {
	    return null;
	}

    }

    /**
     * 保存语音通知/语音调研单条数据
     * 
     * @param called
     * @param ability_type
     * @param app_key
     * @param caller
     * @param chargeNbr
     * @param key
     * @param cust_account
     * @param periphery_code
     * @param userIdentify
     * @param schedule_send_time
     * @param endDate
     * @param content
     * @param voice_name
     * @param push_url
     * @param tts_content
     * @param displayNumber
     * @param batch_number
     * @param status
     * @param completeFileName
     * @param mediaName
     * @param coreDao
     * @return
     */
    public static JSONObject saveNotice(String duduSessionID, String called, String msg_id, String ability_type, String app_key, String caller, String chargeNbr, String key,
	    String cust_account, String periphery_code, String userIdentify, String schedule_send_time, String endDate, String content, String voice_name, String push_url,
	    String tts_content, String displayNumber, String batch_number, String status, String completeFileName, String mediaName, CoreDao coreDao) {
	JSONObject result = new JSONObject();
	MeetInfoBean meetInfoBean = new MeetInfoBean();
	meetInfoBean.setAbility_type(ability_type);
	meetInfoBean.setApp_key(app_key);
	meetInfoBean.setCalled(called);
	meetInfoBean.setCaller(caller);
	meetInfoBean.setChargeNumber(chargeNbr);
	meetInfoBean.setComments("");// 备注
	meetInfoBean.setCust_account(cust_account);
	meetInfoBean.setDuration(0);// 会议总时间
	meetInfoBean.setPeriphery_code(periphery_code);
	meetInfoBean.setStatus("0");// 会议状态
	meetInfoBean.setTotal_amount(2);// 会议总人数
	meetInfoBean.setUser_identify(userIdentify);
	meetInfoBean.setSession_id(duduSessionID);
	meetInfoBean.setMsg_id(msg_id);
	int meetId = -1;
	try {
	    meetId = meetImsService.insert(coreDao, meetInfoBean);
	} catch (Throwable e) {
	    log.error("记录会议信息失败！" + e);
	    return null;
	}
	// 插入语音通知
	SendNoticeBean sendNotice = new SendNoticeBean();
	sendNotice.setMeet_ims_id(meetId);
	sendNotice.setApp_key(app_key);
	sendNotice.setCust_account(cust_account);
	sendNotice.setPeriphery_code(periphery_code);
	sendNotice.setSchedule_send_time(updateSchedule_send_time(schedule_send_time, ability_type));
	sendNotice.setReal_send_time(endDate);
	sendNotice.setCaller(caller);
	sendNotice.setCallee(called);
	sendNotice.setContent(content);
	sendNotice.setStatus(status);// -1未发送，1发送失败，0发送成功
	sendNotice.setSend_count(0);// 发送次数
	sendNotice.setVoice_name(voice_name);
	sendNotice.setMediaName(mediaName);
	sendNotice.setChargeNmr(chargeNbr);
	sendNotice.setChargeKey(key);
	if (StringUtils.isBlank(push_url)) {
	    sendNotice.setPush_url("");
	} else {
	    sendNotice.setPush_url(push_url);
	}
	// 判断使用哪个前导音
	sendNotice.setTts_content(tts_content);
	// sendNotice.setNote(note);
	sendNotice.setCompleteFileName(completeFileName);
	sendNotice.setVoice_type(ability_type);
	sendNotice.setDisplayNumber(displayNumber);
	sendNotice.setBatch_number(batch_number);// 是否同一批次
	/**
	 * 保存duduSessionID
	 */
	sendNotice.setSession_id(duduSessionID);

	try {
	    // 用于传入dao
	    SendNotice sendNoticeModel = new SendNotice();
	    // 实体类转换
	    BeanUtils.copyProperties(sendNotice, sendNoticeModel);// 源,目的
	    if(meetId!=-1){
		 mSendNoticeDao.insert(coreDao, sendNoticeModel);
	    }else{
		return null;
	    }
	} catch (Exception e) {
	    log.error("保存信息失败---meetId=" + meetId, e);
	    return null;
	}
	result.put("voice_id", meetId);
	result.put("session_id", duduSessionID);
	return result;
    }

    /**
     * 批量保存语音通知/语音调研接口(按被叫手机号)
     * 
     * @param called
     * @param ability_type
     * @param app_key
     * @param caller
     * @param chargeNbr
     * @param key
     * @param cust_account
     * @param periphery_code
     * @param userIdentify
     * @param schedule_send_time
     * @param endDate
     * @param content
     * @param voice_name
     * @param push_url
     * @param tts_content
     * @param displayNumber
     * @param batch_number
     * @param status
     * @param completeFileName
     * @param mediaName
     * @param coreDao
     * @return
     */
    public static JSONObject saveNoticesByCalled(String called, String ability_type, String app_key, String caller, String chargeNbr, String key, String cust_account,
	    String periphery_code, String userIdentify, String schedule_send_time, String endDate, String content, String voice_name, String push_url, String tts_content,
	    String displayNumber, String batch_number, String status, String completeFileName, String mediaName, CoreDao coreDao) {
	JSONObject result = new JSONObject();
	JSONObject voice_ids = new JSONObject();
	JSONObject session_ids = new JSONObject();
	String[] calleeStr = called.split(",");
	for (int i = 0; i < calleeStr.length; i++) {
	    String duduSessionID = UUID.randomUUID().toString();
	    String msg_id = "";
	    JSONObject one = saveNotice(duduSessionID, calleeStr[i], msg_id, ability_type, app_key, caller, chargeNbr, key, cust_account, periphery_code, userIdentify,
		    schedule_send_time, endDate, content, voice_name, push_url, tts_content, displayNumber, batch_number, status, completeFileName, mediaName, coreDao);
	    if (one != null) {
		voice_ids.put(calleeStr[i], one.optString("voice_id"));
		session_ids.put(calleeStr[i], one.optString("session_id"));
	    } else {
		voice_ids.put(calleeStr[i], "-1");
		session_ids.put(calleeStr[i], "-1");
	    }

	}
	result.put("voiceIds", voice_ids);
	result.put("sessionIds", session_ids);
	return result;
    }

    /**
     * 批量保存语音通知/语音调研接口(按被叫手机号)
     * 
     * @param calledJsonArray
     * @param ability_type
     * @param app_key
     * @param caller
     * @param chargeNbr
     * @param key
     * @param cust_account
     * @param periphery_code
     * @param userIdentify
     * @param schedule_send_time
     * @param endDate
     * @param content
     * @param voice_name
     * @param push_url
     * @param tts_content
     * @param displayNumber
     * @param batch_number
     * @param status
     * @param completeFileName
     * @param mediaName
     * @param coreDao
     * @return
     */
    public static JSONObject saveNoticesByCalledJsonArray(JSONArray calledJsonArray, String ability_type, String app_key, String caller, String chargeNbr, String key,
	    String cust_account, String periphery_code, String userIdentify, String schedule_send_time, String endDate, String content, String voice_name, String push_url,
	    String tts_content, String displayNumber, String batch_number, String status, String completeFileName, String mediaName, CoreDao coreDao) {
	JSONObject result = new JSONObject();
	JSONObject voice_ids = new JSONObject();
	JSONObject session_ids = new JSONObject();
	for (int i = 0; i < calledJsonArray.size(); i++) {
	    JSONObject phoneAndMsgIdJson = calledJsonArray.getJSONObject(i);
	    String msg_id = phoneAndMsgIdJson.optString("msg_id");
	    String called = phoneAndMsgIdJson.optString("phone");
	    String duduSessionID = UUID.randomUUID().toString();
	    JSONObject one = saveNotice(duduSessionID, called, msg_id, ability_type, app_key, caller, chargeNbr, key, cust_account, periphery_code, userIdentify,
		    schedule_send_time, endDate, content, voice_name, push_url, tts_content, displayNumber, batch_number, status, completeFileName, mediaName, coreDao);
	    if (one != null) {
		voice_ids.put(msg_id, one.optString("voice_id"));
		session_ids.put(msg_id, one.optString("session_id"));
	    } else {
		voice_ids.put(msg_id, "-1");
		session_ids.put(msg_id, "-1");
	    }
	}
	result.put("voiceIds", voice_ids);
	result.put("sessionIds", session_ids);
	return result;
    }

    /**
     * 保存语音通知数据
     * 
     * @param called
     * @param ability_type
     * @param app_key
     * @param caller
     * @param chargeNbr
     * @param key
     * @param cust_account
     * @param periphery_code
     * @param userIdentify
     * @param schedule_send_time
     * @param endDate
     * @param content
     * @param voice_name
     * @param push_url
     * @param tts_content
     * @param displayNumber
     * @param batch_number
     * @param status
     * @param completeFileName
     * @param mediaName
     * @param coreDao
     * @return
     */
    public static JSONObject saveNotices(String called, String ability_type, String app_key, String caller, String chargeNbr, String key, String cust_account,
	    String periphery_code, String userIdentify, String schedule_send_time, String endDate, String content, String voice_name, String push_url, String tts_content,
	    String displayNumber, String batch_number, String status, String completeFileName, String mediaName, CoreDao coreDao, JSONArray calledJsonArray) {
	if (calledJsonArray != null && calledJsonArray.size() > 0) {
	    return saveNoticesByCalledJsonArray(calledJsonArray, ability_type, app_key, caller, chargeNbr, key, cust_account, periphery_code, userIdentify, schedule_send_time,
		    endDate, content, voice_name, push_url, tts_content, displayNumber, batch_number, status, completeFileName, mediaName, coreDao);
	} else {
	    return saveNoticesByCalled(called, ability_type, app_key, caller, chargeNbr, key, cust_account, periphery_code, userIdentify, schedule_send_time, endDate, content,
		    voice_name, push_url, tts_content, displayNumber, batch_number, status, completeFileName, mediaName, coreDao);
	}
    }

    /**
     * 处理预约时间，必须大于当前时间 自建通道即使发送，第三方通道延时3分钟发送
     * 
     * @param schedule_send_time
     * @param abilityType
     *            能力类型
     * @return
     */
    private static String updateSchedule_send_time(String schedule_send_time, String abilityType) {
	Date now = new Date();
	Date nowDely30S = DateUtils.afterDate(now, Calendar.SECOND, 30);// 获取当前时间+30秒
	Date nowAdd = DateUtils.afterDate(now, Calendar.MINUTE, 3);// 获取当前时间+3分钟
	Date scheduleDate = DateUtils.getTimeByFormat(schedule_send_time, "yyyy-MM-dd HH:mm:ss");// 把预约时间转成日期类型
	// 发送时间
	String sendTime = "";
	if (StringUtils.isBlank(schedule_send_time)) { // 没有定时
	    if (abilityType.contains("YonYou")) {
		sendTime = DateUtils.getFormatTime(nowDely30S, "");
	    } else {
		sendTime = DateUtils.getFormatTime(nowAdd, "");
	    }
	} else { // 有定时
	    if (scheduleDate.getTime() - nowAdd.getTime() > 0) {
		sendTime = schedule_send_time;
	    } else {
		if (abilityType.contains("YonYou")) {
		    sendTime = DateUtils.getFormatTime(nowDely30S, "");
		} else {
		    sendTime = DateUtils.getFormatTime(nowAdd, "");
		}
	    }
	}

	return sendTime;
    }

    /**
     * 推送session_id
     * 
     * @param mSendNotice
     * @return
     */
    public static String sendVoiceInfo(PushNoticeInfo mSendNotice) {
	String push_url = mSendNotice.getPush_url();
	StringBuffer pramString = new StringBuffer();
	if (push_url.indexOf("?") != -1) {
	    pramString.append("&voice_id=");
	} else {
	    pramString.append("?voice_id=");
	}
	pramString.append(mSendNotice.getVoice_id());
	pramString.append("&phone=");
	pramString.append(mSendNotice.getPhone());
	pramString.append("&session_id=");
	pramString.append(mSendNotice.getSession_id());
	pramString.append("&errorMsg=");
	if (StringUtils.isNotBlank(mSendNotice.getNote())) {
	    pramString.append(mSendNotice.getNote());
	}

	log.info("通知发送的数据值为：" + pramString.toString());
	String ret = HttpRequest.getData(mSendNotice.getPush_url() + pramString.toString());
	log.info("通知SessionID 推送返回值为：" + ret);
	return ret;
    }

}
